package cn.com.cifi.mars.service.impl;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import cn.com.cifi.mars.bean.bo.DictionaryCodeBO;
import cn.com.cifi.mars.bean.bo.MdmBuildAreaBO;
import cn.com.cifi.mars.bean.bo.PanoPlanCastDecisionBO;
import cn.com.cifi.mars.bean.bo.PriceValueCastDecisionEXTBO;
import cn.com.cifi.mars.common.exception.MsgException;
import cn.com.cifi.mars.constant.CodeEnum;
import cn.com.cifi.mars.constant.Constants;
import cn.com.cifi.mars.constant.IsDeleteEnum;
import cn.com.cifi.mars.constant.ModuleTypeEunm;
import cn.com.cifi.mars.constant.NodeEnum;
import cn.com.cifi.mars.constant.NumberEnum;
import cn.com.cifi.mars.constant.OperatorTypeEnum;
import cn.com.cifi.mars.constant.OrgTypeEunm;
import cn.com.cifi.mars.constant.ProcessingStateEnum;
import cn.com.cifi.mars.constant.SalyTypeEnum;
import cn.com.cifi.mars.constant.VersionCreateEnum;
import cn.com.cifi.mars.constant.VersionStatusEnum;
import cn.com.cifi.mars.constant.VersionTypeEunm;
import cn.com.cifi.mars.entity.MdmStage;
import cn.com.cifi.mars.entity.PanoplanBuildPlanItem;
import cn.com.cifi.mars.entity.PanoplanBuildPlanItemDetail;
import cn.com.cifi.mars.entity.PriceValueOrg;
import cn.com.cifi.mars.entity.PriceVersion;
import cn.com.cifi.mars.entity.SysNotice;
import cn.com.cifi.mars.entity.common.IdmUser;
import cn.com.cifi.mars.mapper.mars.PriceValueOrgMapper;
import cn.com.cifi.mars.mapper.mars.PriceVersionMapper;
import cn.com.cifi.mars.service.BuildAreaService;
import cn.com.cifi.mars.service.CommonService;
import cn.com.cifi.mars.service.PanoplanBuildPlanService;
import cn.com.cifi.mars.service.PriceValueOrgService;
import cn.com.cifi.mars.service.PriceVersionService;
import cn.com.cifi.mars.service.PriceVersionValueOrgService;
import cn.com.cifi.mars.service.ProjectLockRecordService;
import cn.com.cifi.mars.service.StageService;
import cn.com.cifi.mars.service.SysDictionaryService;
import cn.com.cifi.mars.service.SysNoticeService;
import cn.com.cifi.mars.util.UUIDUtils;
import lombok.extern.slf4j.Slf4j;

/**
 * <p>
 * 货值组织属性结构表 服务实现类
 * </p>
 *
 * @author yyd
 * @since 2019-09-11
 */
@Service
@Slf4j
public class PriceValueOrgServiceImpl extends ServiceImpl<PriceValueOrgMapper, PriceValueOrg> implements PriceValueOrgService {

    @Autowired
    private PriceValueOrgMapper priceValueOrgMapper;

    @Autowired
    private PriceVersionMapper priceVersionMapper;

    @Autowired
    private PriceVersionValueOrgService priceVersionValueOrgService;

    @Autowired
    private PanoplanBuildPlanService panoplanBuildPlanService;

    @Autowired
    private PriceVersionValueOrgServiceImpl priceVersionValueOrgServiceImpl;

    @Autowired
    private StageService stageService;

    @Autowired
    private PriceVersionService priceVersionService;

    @Autowired
    private SysDictionaryService sysDictionaryService;

    @Autowired
    private BuildAreaService buildAreaService;

    @Autowired
    private SysNoticeService sysNoticeMapper;

    @Autowired
    private CommonService commonService;

    @Autowired
    private SysNoticeService sysNoticeService;

    @Autowired
    private ProjectLockRecordService projectLockRecordService;

    static List<String> isParkList = Arrays.asList("139","140","141","142","154");

    @Override
    public List<PriceValueOrg> selectBuildByVersionId(String oldVersionId, String key, String o, int key1) {
        return  priceValueOrgMapper.selectBuildByVersionId(oldVersionId, key, o, IsDeleteEnum.NO.getKey());
    }

    @Override
    public void updateCastDecisionOrgValue(SysNotice sysNotice, IdmUser imdUser) {
        //查看货值版本信息
        String versionId = sysNotice.getAffectedValueVersionId();
        PriceVersion priceVersion = priceVersionMapper.selectByPrimaryKey(versionId);
        if (priceVersion == null){
            throw new MsgException(CodeEnum.NON_EXISTENT_VERSIONS_ORG);
        }

        //查看分期是否有战规后版本信息，如果有则不处理
        List<PriceVersion> priceVersions = priceVersionMapper.selectApprovalVersionByFidAndTypesAndStates(priceVersion.getProjectfId(),
                Arrays.asList(VersionTypeEunm.WARPLAN.getKey(), VersionTypeEunm.GETPRICE.getKey(), VersionTypeEunm.DYNAMIC.getKey()),
                Arrays.asList(VersionStatusEnum.NOTPREPARED.getKey(), VersionStatusEnum.ORGANIZATION.getKey(), VersionStatusEnum.EXAMINEDAPPROVED.getKey(), VersionStatusEnum.APPROVED.getKey(), VersionStatusEnum.FAILUREAPPROVED.getKey(), VersionStatusEnum.SUCCESSAPPROVED.getKey(), VersionStatusEnum.SYSGENERATION.getKey()),
                IsDeleteEnum.NO.getKey());
        if (CollectionUtils.isEmpty(priceVersions)){

            //查看版本状态(代编制、编制中、待提交审批、审批已驳回直接刷新，审批中不处理，审批通过生成新版本)
            String stagesId = sysNotice.getStagesId();
            String versionState = priceVersion.getVersionState();
            if(versionState.equals(VersionStatusEnum.SUCCESSAPPROVED.getKey())){

                //手动生成
                priceVersionValueOrgService.createSysCastDecisionVersion(stagesId, VersionCreateEnum.MANUALCREATE.getKey(), imdUser, null, null);
            }else{
                //自动刷新
                LocalDateTime now = LocalDateTime.now();

                //获取最新的投资版楼栋计划
                PanoPlanCastDecisionBO panoPlanCastDecisionBO = panoplanBuildPlanService.selectNewestByFid(stagesId, Arrays.asList(VersionTypeEunm.INVESTMENT.getValue()), IsDeleteEnum.NO.getKey());

                ///将节点为取预售证时间的存储在指定Map中
                Map<String, LocalDateTime> openTimeMap = new HashMap<String, LocalDateTime>();
                Map<String, LocalDateTime> openTimeActualMap = new HashMap<String, LocalDateTime>();
                Map<String, LocalDateTime> advanceSaleTimeMap = new HashMap<String, LocalDateTime>();
                Map<String, LocalDateTime> advanceSaleTimeActualMap = new HashMap<String, LocalDateTime>();
                Map<String, LocalDateTime> supplyTimeMap = new HashMap<String, LocalDateTime>();
                Map<String, LocalDateTime> supplyTimeActualMap = new HashMap<String, LocalDateTime>();
                Map<String, LocalDateTime> openSaleTimeMap = new HashMap<String, LocalDateTime>();
                Map<String, LocalDateTime> openSaleTimeActualMap = new HashMap<String, LocalDateTime>();
                Map<String, LocalDateTime> cappingTimeMap = new HashMap<String, LocalDateTime>();
                Map<String, LocalDateTime> cappingTimeActualMap = new HashMap<String, LocalDateTime>();
                Map<String, LocalDateTime> completedTimeMap = new HashMap<String, LocalDateTime>();
                Map<String, LocalDateTime> completedTimeActualMap = new HashMap<String, LocalDateTime>();
                Map<String, LocalDateTime> carryOverTimeMap = new HashMap<String, LocalDateTime>();
                Map<String, LocalDateTime> carryOverTimeActualMap = new HashMap<String, LocalDateTime>();
                Map<String, LocalDateTime> actualDeliveryTimeMap = new HashMap<String, LocalDateTime>();
                Map<String, LocalDateTime> actualDeliveryTimeActualMap = new HashMap<String, LocalDateTime>();
                Map<String, LocalDateTime> contractDeliveryTimeMap = new HashMap<String, LocalDateTime>();
                Map<String, LocalDateTime> contractDeliveryTimeActualMap = new HashMap<String, LocalDateTime>();
                List<PanoplanBuildPlanItemDetail> details = panoPlanCastDecisionBO.getDetails();
                if(CollectionUtils.isNotEmpty(details)){
                    for (int i = 0;i < details.size(); i++){
                        PanoplanBuildPlanItemDetail panoplanBuildPlanItemDetail = details.get(i);
                        String nodeCode = panoplanBuildPlanItemDetail.getNodeCode();
                        if(StringUtils.isNotEmpty(nodeCode) && nodeCode.equals(NodeEnum.JT_LCB_00002.getKey())){
                            openTimeMap.put(panoplanBuildPlanItemDetail.getPkId(), panoplanBuildPlanItemDetail.getPlannedFinishDate());
                            openTimeActualMap.put(panoplanBuildPlanItemDetail.getPkId(), panoplanBuildPlanItemDetail.getActualFinishDate());
                        }else if(StringUtils.isNotEmpty(nodeCode) && nodeCode.equals(NodeEnum.JT_YJ_00001.getKey())){
                            advanceSaleTimeMap.put(panoplanBuildPlanItemDetail.getPkId(), panoplanBuildPlanItemDetail.getPlannedFinishDate());
                            advanceSaleTimeActualMap.put(panoplanBuildPlanItemDetail.getPkId(), panoplanBuildPlanItemDetail.getActualFinishDate());
                        }else if(StringUtils.isNotEmpty(nodeCode) && nodeCode.equals(NodeEnum.JT_YJ_00002.getKey())){
                            supplyTimeMap.put(panoplanBuildPlanItemDetail.getPkId(), panoplanBuildPlanItemDetail.getPlannedFinishDate());
                            supplyTimeActualMap.put(panoplanBuildPlanItemDetail.getPkId(), panoplanBuildPlanItemDetail.getActualFinishDate());
                        }else if(StringUtils.isNotEmpty(nodeCode) && nodeCode.equals(NodeEnum.JT_LCB_00003.getKey())){
                            openSaleTimeMap.put(panoplanBuildPlanItemDetail.getPkId(), panoplanBuildPlanItemDetail.getPlannedFinishDate());
                            openSaleTimeActualMap.put(panoplanBuildPlanItemDetail.getPkId(), panoplanBuildPlanItemDetail.getActualFinishDate());
                        }else if(StringUtils.isNotEmpty(nodeCode) && nodeCode.equals(NodeEnum.JT_YJ_00003.getKey())){
                            cappingTimeMap.put(panoplanBuildPlanItemDetail.getPkId(), panoplanBuildPlanItemDetail.getPlannedFinishDate());
                            cappingTimeActualMap.put(panoplanBuildPlanItemDetail.getPkId(), panoplanBuildPlanItemDetail.getActualFinishDate());
                        }else if(StringUtils.isNotEmpty(nodeCode) && nodeCode.equals(NodeEnum.JT_LCB_00004.getKey())){
                            completedTimeMap.put(panoplanBuildPlanItemDetail.getPkId(), panoplanBuildPlanItemDetail.getPlannedFinishDate());
                            completedTimeActualMap.put(panoplanBuildPlanItemDetail.getPkId(), panoplanBuildPlanItemDetail.getActualFinishDate());
                        }else if(StringUtils.isNotEmpty(nodeCode) && nodeCode.equals(NodeEnum.JT_LCB_00006.getKey())){
                            carryOverTimeMap.put(panoplanBuildPlanItemDetail.getPkId(), panoplanBuildPlanItemDetail.getPlannedFinishDate());
                            carryOverTimeActualMap.put(panoplanBuildPlanItemDetail.getPkId(), panoplanBuildPlanItemDetail.getActualFinishDate());
                        }else if(StringUtils.isNotEmpty(nodeCode) && nodeCode.equals(NodeEnum.JT_LCB_00005.getKey())){
                            actualDeliveryTimeMap.put(panoplanBuildPlanItemDetail.getPkId(), panoplanBuildPlanItemDetail.getPlannedFinishDate());
                            actualDeliveryTimeActualMap.put(panoplanBuildPlanItemDetail.getPkId(), panoplanBuildPlanItemDetail.getActualFinishDate());
                        }else if(StringUtils.isNotEmpty(nodeCode) && nodeCode.equals(NodeEnum.NODE_000.getKey())){
                            contractDeliveryTimeMap.put(panoplanBuildPlanItemDetail.getPkId(), panoplanBuildPlanItemDetail.getPlannedFinishDate());
                            contractDeliveryTimeActualMap.put(panoplanBuildPlanItemDetail.getPkId(), panoplanBuildPlanItemDetail.getActualFinishDate());
                        }
                    }
                }

                List<PanoplanBuildPlanItem> productItems = panoPlanCastDecisionBO.getProductItems();
                for (PanoplanBuildPlanItem productItem : productItems){
                    String saleNum = productItem.getSaleNum();
                    if(StringUtils.isNotEmpty(saleNum) && (saleNum.equals(SalyTypeEnum.SALABLE.getKey())
                            || saleNum.equals(SalyTypeEnum.STAGE_SELF_SUSTAINMENT.getKey()))){
                        LocalDateTime supplyTime = supplyTimeMap.get(productItem.getId());
                        if(supplyTime == null){
                            throw new MsgException(CodeEnum.NON_PANO_TIME);
                        }
                    }
                }

                //找上级分类
                Map<String, DictionaryCodeBO> dicMap = new HashMap<>();
                List<String> productCodes = Optional.of(productItems).orElseGet(ArrayList::new)
                        .stream().map(PanoplanBuildPlanItem::getProductTypeNum)
                        .collect(Collectors.toList());
                if(CollectionUtils.isNotEmpty(productCodes)){
                    List<DictionaryCodeBO> dicType = sysDictionaryService.selectByCodes(productCodes);
                    if(CollectionUtils.isNotEmpty(dicType)){
                        for(DictionaryCodeBO bo : dicType){
                            dicMap.put(bo.getChildCode(),bo);
                        }
                    }
                }

                //货值产品构成
                Map<String, PriceValueCastDecisionEXTBO> productValueMap = new HashMap<String, PriceValueCastDecisionEXTBO>();
                List<PriceValueCastDecisionEXTBO> productOrgs = priceValueOrgMapper.selectProductByVersionId(priceVersion.getId(), OrgTypeEunm.ORG_PRODUCT.getKey(), IsDeleteEnum.NO.getKey());
                for (PriceValueCastDecisionEXTBO priceValueOrg : productOrgs) {
                    String code = priceValueOrg.getGroupId()+"&"+priceValueOrg.getBatchCode()+"&"+priceValueOrg.getProductCode()
                            +"&"+priceValueOrg.getFreeType()+"&"+priceValueOrg.getBusinessType()+"&"+priceValueOrg.getProType();
                    productValueMap.put(code, priceValueOrg);
                }

                List<PriceValueOrg> insertProductList = new ArrayList<PriceValueOrg>();
                List<PriceValueOrg> deleteProductList = new ArrayList<PriceValueOrg>();
                List<PriceValueOrg> updateProductList = new ArrayList<PriceValueOrg>();
                Map<String, List<PriceValueOrg>> productMap = new HashMap<String, List<PriceValueOrg>>();
                for (PanoplanBuildPlanItem productItem : productItems){

                    String pidCode = productItem.getBatchId()+"&"+productItem.getBatchNum();

                    String code = productItem.getBatchId()+"&"+productItem.getBatchNum()+"&"+productItem.getProductTypeNum()
                            +"&"+productItem.getDecorateNum()+"&"+productItem.getSaleNum()+"&"+productItem.getProTypeCode();

                    //查看是否有变动
                    PriceValueOrg priceValueOrg = productValueMap.get(code);
                    if (priceValueOrg != null){

                        boolean isUpdate = false;

                        Integer panoRoomNum = productItem.getBatchRoomNum();
                        if (panoRoomNum <= 0){
                            String message =  "产品构成信息不完整:"+productItem.getProductTypeName()+"套数/个数小于等于0";
                            CodeEnum.NON_PANOPLAN_PRODUT.setMessage(message);
                            throw new MsgException(CodeEnum.NON_PANOPLAN_PRODUT);
                        }
                        Integer valueNum = priceValueOrg.getNum();
                        if (!valueNum.equals(panoRoomNum)){
                            priceValueOrg.setNum(panoRoomNum);

                            if (!isParkList.contains(productItem.getProductTypeNum())){
                                priceValueOrg.setRoomNum(panoRoomNum);
                            }else{
                                priceValueOrg.setParkingNum(panoRoomNum);
                                priceValueOrg.setNotCommodityValue(priceVersionValueOrgServiceImpl.BigDecimalMUL(priceValueOrg.getAveragePriceParking(), new BigDecimal(panoRoomNum)));
                            }

                            isUpdate = true;
                        }

                        BigDecimal panoSaleArea = productItem.getBatchSaleArea() == null ? new BigDecimal(0) : productItem.getBatchSaleArea();
                        if (panoSaleArea.compareTo(new BigDecimal(0)) <= 0){
                            if (!isParkList.contains(productItem.getProductTypeNum())){
                                String message = "产品构成信息不完整:"+productItem.getProductTypeName()+"面积小于等于0";
                                CodeEnum.NON_PANOPLAN_PRODUT.setMessage(message);
                                throw new MsgException(CodeEnum.NON_PANOPLAN_PRODUT);
                            }
                        }
                        BigDecimal valueSaleArea = priceValueOrg.getSaleArea();
                        if (valueSaleArea.compareTo(panoSaleArea) != 0){
                            priceValueOrg.setSaleArea(panoSaleArea);

                            if (!isParkList.contains(productItem.getProductTypeNum())){
                                priceValueOrg.setHouseCommodityValue(priceVersionValueOrgServiceImpl.BigDecimalMUL(priceValueOrg.getAveragePriceParking(), valueSaleArea));
                            }

                            isUpdate = true;
                        }

                        if (isUpdate){
                            updateProductList.add(priceValueOrg);
                        }
                    }else{
                        //新增产品构成
                        priceValueOrg = new PriceValueOrg();

                        //赋值基本信息
                        String productId = UUIDUtils.create();
                        priceValueOrg.setId(productId);
                        priceValueOrg.setVersionId(versionId);
                        priceValueOrg.setType(OrgTypeEunm.ORG_PRODUCT.getKey());
                        priceValueOrg.setOrgId("");
                        priceValueOrg.setOrgCode(productItem.getProductTypeNum());
                        priceValueOrg.setOrgName(productItem.getProductTypeName());

                        //赋值楼栋计划信息
                        priceValueOrg.setPanoBatchSaleArea(productItem.getTotalSaleArea());
                        priceValueOrg.setPanoTotalRoomNum(productItem.getTotalRoomNum());
                        priceValueOrg.setPanoTotalSaleArea(productItem.getTotalSaleArea());
                        priceValueOrg.setPanoBatchRoomNum(productItem.getBatchRoomNum());
                        priceValueOrg.setPanoBatchSaleArea(productItem.getBatchSaleArea());
                        priceValueOrg.setPanoSalePark(productItem.getSalePark());
                        priceValueOrg.setPanoTotalBuildArea(productItem.getTotalBuildArea());
                        priceValueOrg.setPanoBatchBuildArea(productItem.getBatchBuildArea());

                        //赋值属性标签信息
                        if(StringUtils.isNotEmpty(productItem.getSaleNum()) && StringUtils.isNotEmpty(productItem.getSaleType())){
                            priceValueOrg.setBusinessType(productItem.getSaleNum());
                            priceValueOrg.setBusinessTypeName(productItem.getSaleType());
                        }else{
                            throw new MsgException(CodeEnum.NON_EXISTENT_BUSINESSTYPE);
                        }
                        if(StringUtils.isNotEmpty(productItem.getDecorateNum()) && StringUtils.isNotEmpty(productItem.getDecorateName())){
                            priceValueOrg.setFreeType(productItem.getDecorateNum());
                            priceValueOrg.setFreeTypeName(productItem.getDecorateName());
                        }else{
                            throw new MsgException(CodeEnum.NON_EXISTENT_FREETYPE);
                        }
                        if(StringUtils.isNotEmpty(productItem.getProTypeCode()) && StringUtils.isNotEmpty(productItem.getProType())){
                            priceValueOrg.setProType(productItem.getProTypeCode());
                            priceValueOrg.setProTypeName(productItem.getProType());
                        }else{
                            throw new MsgException(CodeEnum.NON_EXISTENT_PROTYPE);
                        }
                        priceValueOrg.setProductCode(productItem.getProductTypeNum());
                        priceValueOrg.setProductType(productItem.getProductTypeName());
                        priceValueOrg.setProProductCode(dicMap.get(productItem.getProductTypeNum()).getParentCode());
                        priceValueOrg.setProProductType(dicMap.get(productItem.getProductTypeNum()).getParentName());

                        //匹配时间节点
                        priceValueOrg.setOpenTime(openTimeMap.get(productItem.getId()));
                        priceValueOrg.setOpenTimeActual(openTimeActualMap.get(productItem.getId()));
                        priceValueOrg.setAdvanceSaleTime(advanceSaleTimeMap.get(productItem.getId()));
                        priceValueOrg.setAdvanceSaleTimeActual(advanceSaleTimeActualMap.get(productItem.getId()));
                        priceValueOrg.setSupplyTime(supplyTimeMap.get(productItem.getId()));
                        priceValueOrg.setSupplyTimeActual(supplyTimeActualMap.get(productItem.getId()));
                        priceValueOrg.setOpenSaleTime(openSaleTimeMap.get(productItem.getId()));
                        priceValueOrg.setOpenSaleTimeActual(openSaleTimeActualMap.get(productItem.getId()));
                        priceValueOrg.setCappingTime(cappingTimeMap.get(productItem.getId()));
                        priceValueOrg.setCappingTimeActual(cappingTimeActualMap.get(productItem.getId()));
                        priceValueOrg.setCompletedTime(completedTimeMap.get(productItem.getId()));
                        priceValueOrg.setCompletedTimeActual(completedTimeActualMap.get(productItem.getId()));
                        priceValueOrg.setCarryOverTime(carryOverTimeMap.get(productItem.getId()));
                        priceValueOrg.setCarryOverTimeActual(carryOverTimeActualMap.get(productItem.getId()));
                        priceValueOrg.setActualDeliveryTime(actualDeliveryTimeMap.get(productItem.getId()));
                        priceValueOrg.setActualDeliveryTimeActual(actualDeliveryTimeActualMap.get(productItem.getId()));
                        priceValueOrg.setContractDeliveryTime(contractDeliveryTimeMap.get(productItem.getId()));
                        priceValueOrg.setContractDeliveryTimeActual(contractDeliveryTimeActualMap.get(productItem.getId()));

                        //赋值货值信息
                        priceValueOrg.setNum(productItem.getBatchRoomNum());
                        if(isParkList.contains(productItem.getProductTypeNum())){
                            priceValueOrg.setIsParking(IsDeleteEnum.YES.getKey());
                            priceValueOrg.setParkingNum(productItem.getBatchRoomNum());
                        }else{
                            priceValueOrg.setIsParking(IsDeleteEnum.NO.getKey());
                            priceValueOrg.setRoomNum(productItem.getBatchRoomNum());
                        }
                        priceValueOrg.setIsSplit(IsDeleteEnum.NO.getKey());
                        priceValueOrg.setIsDelete(IsDeleteEnum.NO.getKey());
                        priceValueOrg.setCreateTime(now);
                        priceValueOrg.setUpdateTime(now);

                        Integer batchRoomNum = productItem.getBatchRoomNum();
                        priceValueOrg.setNum(batchRoomNum);
                        if (batchRoomNum <= 0){
                            String message =  "产品构成信息不完整:"+productItem.getProductTypeName()+"套数/个数小于等于0";
                            CodeEnum.NON_PANOPLAN_PRODUT.setMessage(message);
                            throw new MsgException(CodeEnum.NON_PANOPLAN_PRODUT);
                        }

                        BigDecimal saleArea = productItem.getBatchSaleArea() == null ? new BigDecimal(0) : productItem.getBatchSaleArea();
                        priceValueOrg.setSaleArea(saleArea);
                        if (saleArea.compareTo(new BigDecimal(0)) <= 0){
                            if (!isParkList.contains(productItem.getProductTypeNum())){
                                String message = "产品构成信息不完整:"+productItem.getProductTypeName()+"面积小于等于0";
                                CodeEnum.NON_PANOPLAN_PRODUT.setMessage(message);
                                throw new MsgException(CodeEnum.NON_PANOPLAN_PRODUT);
                            }
                        }
                    }

                    productValueMap.remove(code);

                    List<PriceValueOrg> valueOrgs = productMap.get(pidCode);
                    if (CollectionUtils.isEmpty(valueOrgs)){
                        valueOrgs = new ArrayList<PriceValueOrg>();
                    }
                    valueOrgs.add(priceValueOrg);
                    productMap.put(pidCode, valueOrgs);
                }

                List<String> deleteProductIds = new ArrayList<>();
                if (CollectionUtils.isNotEmpty(productValueMap)){
                    for (Map.Entry<String, PriceValueCastDecisionEXTBO> productValuemap : productValueMap.entrySet()){
                        PriceValueCastDecisionEXTBO value = productValuemap.getValue();
                        value.setIsDelete(IsDeleteEnum.YES.getKey());
                        deleteProductList.add(value);

                        deleteProductIds.add(value.getId());
                    }
                }

                //批次信息
                Map<String, PriceValueCastDecisionEXTBO> batchValueMap = new HashMap<String, PriceValueCastDecisionEXTBO>();
                List<PriceValueCastDecisionEXTBO> batchOrgs = priceValueOrgMapper.selectBatchByVersionId(priceVersion.getId(), OrgTypeEunm.ORG_PRODUCT.getKey(), IsDeleteEnum.NO.getKey());
                for (PriceValueCastDecisionEXTBO priceValueOrg : batchOrgs) {
                    String code = priceValueOrg.getGroupId()+"&"+priceValueOrg.getBatchCode();
                    batchValueMap.put(code, priceValueOrg);
                }
                List<PanoplanBuildPlanItem> batchItems = panoPlanCastDecisionBO.getBatchItems();
                for (PanoplanBuildPlanItem batchItem : batchItems){
                    String code = batchItem.getBatchId()+"&"+batchItem.getBatchNum();
                    //查看是否有变动
                    PriceValueOrg priceValueOrg = batchValueMap.get(code);
                    String batchId = null;
                    if (priceValueOrg != null){
                        batchId = priceValueOrg.getId();
                    }else{
                        //新增批次
                        priceValueOrg = new PriceValueOrg();
                        batchId = UUIDUtils.create();
                        priceValueOrg.setId(batchId);
                        priceValueOrg.setVersionId(versionId);
                        priceValueOrg.setType(OrgTypeEunm.ORG_BATCH.getKey());
                        priceValueOrg.setOrgId("");
                        priceValueOrg.setOrgCode(batchItem.getBatchNum());
                        priceValueOrg.setOrgName(NumberEnum.getValueByKey(batchItem.getBatchNum().trim())+"批次");
                        priceValueOrg.setIsDelete(IsDeleteEnum.NO.getKey());
                        priceValueOrg.setCreateTime(now);
                        priceValueOrg.setUpdateTime(now);
                    }
                    //初始化数据
                    priceValueOrg.setNum(0);
                    priceValueOrg.setRoomNum(0);
                    priceValueOrg.setParkingNum(0);
                    priceValueOrg.setForsaleParkingNum(0);
                    priceValueOrg.setSaleArea(BigDecimal.ZERO);
                    priceValueOrg.setAveragePriceHouse(BigDecimal.ZERO);
                    priceValueOrg.setAveragePriceParking(BigDecimal.ZERO);
                    priceValueOrg.setHouseCommodityValue(BigDecimal.ZERO);
                    priceValueOrg.setNotCommodityValue(BigDecimal.ZERO);
                    priceValueOrg.setCommodityValue(BigDecimal.ZERO);
                    //从新计算货值
                    List<PriceValueOrg> productvalues = productMap.get(code);
                    if (CollectionUtils.isNotEmpty(productvalues)){
                        for (PriceValueOrg productvalue : productvalues){
                            String pid = productvalue.getPid();
                            if (StringUtils.isNotEmpty(pid.trim())){
                                productvalue.setPid(pid);
                                insertProductList.add(priceValueOrg);
                            }
                            priceVersionValueOrgServiceImpl.valueUpSummary(priceValueOrg, productvalue);
                        }
                    }
                }
            }
        }
    }

    @Override
    public String updateDynamicOrgValue(SysNotice sysNotice, IdmUser idmUser) {
        String resultVersionId = "";
        //查看版本状态(代编制、编制中、待提交审批、审批已驳回直接刷新，审批中不处理，审批通过、系统生成生成新版本)
        String stageId = sysNotice.getStagesId();

        String taskSource = sysNotice.getTaskSource();
        LocalDateTime now = LocalDateTime.now();

        //查看是动态版还是还是战规版
        PriceVersion newestDynamicPriceVersion = priceVersionService.getNewestPriceVersionAllVersionState(stageId);

        //去除投资版
        if(newestDynamicPriceVersion != null){
            if(newestDynamicPriceVersion.getVersionType().equals(VersionTypeEunm.INVESTMENT.getKey())){
                newestDynamicPriceVersion = null;
            }
        }

        //如果没有战规后版本则生成版本
        if (newestDynamicPriceVersion == null){
            resultVersionId = priceVersionValueOrgService.createSysDynamicVersion(stageId, taskSource, VersionCreateEnum.MANUALCREATE.getKey(), idmUser, null, null, null, null);
            //处理待办信息
            manualPriceHandleNoticeInfo(sysNotice, idmUser, stageId, now, newestDynamicPriceVersion);
            return resultVersionId;
        }

        //查询指定分期信息
        MdmStage mdmStage = stageService.selectById(stageId);
        if(mdmStage == null){
            throw new MsgException(CodeEnum.STAGE_NON_EXISTENT);
        }

        //如果项目在锁定状态中，不能刷新货值版本
        boolean lockByProjectId = projectLockRecordService.isLockByProjectId(mdmStage.getProjectId());
        if(!lockByProjectId){
            String versionState = newestDynamicPriceVersion.getVersionState();
            String versionType = newestDynamicPriceVersion.getVersionType();
            if (versionState.equals(VersionStatusEnum.NOTPREPARED.getKey()) || versionState.equals(VersionStatusEnum.ORGANIZATION.getKey())
                    || versionState.equals(VersionStatusEnum.EXAMINEDAPPROVED.getKey()) || versionState.equals(VersionStatusEnum.FAILUREAPPROVED.getKey())){
                if(versionType.equals(VersionTypeEunm.DYNAMIC.getKey())){
                    //获取最新的动态版楼栋计划
                    PanoPlanCastDecisionBO panoPlanCastDecisionBO = panoplanBuildPlanService.selectNewestWarPlanByFid(stageId, VersionTypeEunm.DYNAMIC.getKey(), IsDeleteEnum.NO.getKey());
                    //获取最新的动态版楼栋面积
                    MdmBuildAreaBO mdmProductWarPlanBO = buildAreaService.selectNewestByFid(stageId, VersionTypeEunm.DYNAMIC.getKey(), IsDeleteEnum.NO.getKey());
                    if(mdmProductWarPlanBO == null){
                        throw new MsgException(CodeEnum.NON_GROUPBLD_AREA);
                    }
                    //货值刷新
                    priceVersionValueOrgServiceImpl.priceValueRefreshInfo(stageId, newestDynamicPriceVersion, panoPlanCastDecisionBO, mdmProductWarPlanBO, null, null, null);
                    resultVersionId = newestDynamicPriceVersion.getId();
                }else if(versionType.equals(VersionTypeEunm.GETPRICE.getKey()) || versionType.equals(VersionTypeEunm.WARPLAN.getKey())){
                    resultVersionId = priceVersionValueOrgServiceImpl.createSysDynamicVersion(stageId, VersionTypeEunm.DYNAMIC.getKey(), VersionCreateEnum.MANUALCREATE.getKey(), idmUser, null, null,null, null);
                    return resultVersionId;
                }
            }else if(versionState.equals(VersionStatusEnum.SUCCESSAPPROVED.getKey()) || versionState.equals(VersionStatusEnum.SYSGENERATION.getKey())){
                resultVersionId = priceVersionValueOrgServiceImpl.createSysDynamicVersion(stageId, VersionTypeEunm.DYNAMIC.getKey(), VersionCreateEnum.MANUALCREATE.getKey(), idmUser, null, null,null, null);
            }else if (versionState.equals(VersionStatusEnum.APPROVED.getKey())){
                return resultVersionId;
            }
            //处理待办信息
            manualPriceHandleNoticeInfo(sysNotice, idmUser, stageId, now, newestDynamicPriceVersion);
        }else{
            log.info("######################       updateDynamicOrgValue    lockByProjectId:"+CodeEnum.PROJECTID_TO_LOCK.getMessage());
            throw new MsgException(CodeEnum.PROJECTID_TO_LOCK);
        }
        return resultVersionId;
    }

    @Transactional(rollbackFor=Exception.class)
    private void manualPriceHandleNoticeInfo(SysNotice sysNotice, IdmUser idmUser, String stageId, LocalDateTime now, PriceVersion newestDynamicPriceVersion) {
        try {
            //处理代办信息
            sysNotice.setHandlePerson(idmUser.getAlias());
            sysNotice.setState(ProcessingStateEnum.PROCESSED.getKey());
            sysNotice.setProcessingTime(now);
            sysNotice.setUpdateBy(idmUser.getAlias());
            sysNotice.setUpdateTime(now);
            sysNoticeMapper.updateById(sysNotice);
            //删除门户代办消息
            commonService.updatePortalProcess(sysNotice.getPortalInstanceId(), OperatorTypeEnum.TRANSFERRED_TO_OFFICE.getKey(), idmUser, null);

            //将所有待处理的系统任务和待办都消除
            List<SysNotice> notices = new ArrayList<SysNotice>();
            if (newestDynamicPriceVersion != null){
                notices = sysNoticeService.selectModeByProjectFidAndVersionType(stageId, ModuleTypeEunm.PRICE.getKey(), newestDynamicPriceVersion.getVersionType(), ProcessingStateEnum.UNTREATED.getKey(), IsDeleteEnum.NO.getKey());
            }else{
                notices = sysNoticeService.selectModeByProjectFidAndVersionType(stageId, ModuleTypeEunm.PRICE.getKey(), VersionTypeEunm.INVESTMENT.getKey(), ProcessingStateEnum.UNTREATED.getKey(), IsDeleteEnum.NO.getKey());
            }

            if (CollectionUtils.isNotEmpty(notices)){
                for (SysNotice notice : notices){
                    notice.setState(ProcessingStateEnum.PROCESSED.getKey());
                    notice.setProcessingTime(now);
                    notice.setUpdateTime(now);
                    notice.setHandlePerson(Constants.SYS);
                    notice.setUpdateBy(Constants.SYS);
                    sysNoticeMapper.updateById(notice);
                    String instanceId = notice.getPortalInstanceId();
                    //删除门户代办消息
                    if(StringUtils.isNotEmpty(instanceId)){
                        commonService.updatePortalProcess(instanceId, OperatorTypeEnum.TRANSFERRED_TO_OFFICE.getKey(), idmUser, null);
                    }
                }
            }
        }catch (Exception e){
            log.error("############   货值待办处理失败:"+stageId +"；",e);
        }
    }

    @Override
    @Transactional
    public void updateRefreshValueBatch(String versionId, PriceVersion priceVersion, List<PriceValueOrg> stageList, List<PriceValueOrg> groupUpdateList, List<PriceValueOrg> productUpdateList, List<PriceValueOrg> buildUpdateList, List<PriceValueOrg> hoseSoleList, List<PriceValueOrg> sortParkList) {
        //删除原有面积段以及车位信息
        priceValueOrgMapper.deleteHouseAndParkingByVersionId(versionId);

        priceVersionMapper.updateByPrimaryKeySelective(priceVersion);

        if (CollectionUtils.isNotEmpty(stageList)) {
            priceValueOrgMapper.updateBatch(stageList);
        }

        if (CollectionUtils.isNotEmpty(groupUpdateList)) {
            priceValueOrgMapper.updateBatch(groupUpdateList);
        }

        if (CollectionUtils.isNotEmpty(productUpdateList)) {
            priceValueOrgMapper.updateBatch(productUpdateList);
        }

        if (CollectionUtils.isNotEmpty(buildUpdateList)) {
            priceValueOrgMapper.updateBatch(buildUpdateList);
        }

        if(CollectionUtils.isNotEmpty(hoseSoleList)){
            priceValueOrgMapper.insertBatch(hoseSoleList);
        }
        if(CollectionUtils.isNotEmpty(sortParkList)){
            priceValueOrgMapper.insertBatch(sortParkList);
        }
    }
}
